use futures::StreamExt;
use pcap::{Active, Capture, Device, Packet, PacketCodec, PacketStream};

pub struct RawPcapSocket {
    stream: PacketStream<Active, BoxCodec>,
}

pub struct BoxCodec;

impl PacketCodec for BoxCodec {
    type Item = Box<[u8]>;

    fn decode(&mut self, packet: Packet) -> Self::Item {
        packet.data.into()
    }
}

impl RawPcapSocket {
    pub fn new(filter: &str) -> Self {
        // let device = Device::lookup().unwrap().unwrap();
        let device = Device::list().unwrap().into_iter().find(|d| d.name == "lo").unwrap();
        log::info!("start capture on device [{}]", device.name);
        let mut capture = Capture::from_device(device)
            .unwrap()
            .immediate_mode(true)
            .open()
            .unwrap();
        capture
            .filter(filter, true)
            .expect("set capture filter error");
        let capture = capture.setnonblock().unwrap();
        let stream = capture.stream(BoxCodec {}).unwrap();
        Self { stream }
    }
    pub async fn next_packet(&mut self) -> Option<Box<[u8]>> {
        match self.stream.next().await {
            Some(Ok(pkt)) => Some(pkt),
            Some(Err(e)) => {
                log::error!("capture packet error {}", e);
                None
            }
            None => None,
        }
    }
}
